package com.hhkj.api.order.service.biz.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageInfo;
import com.hhkj.admin.order.common.cont.OrderConst;
import com.hhkj.admin.order.domain.Order;
import com.hhkj.admin.order.domain.OrderItem;
import com.hhkj.admin.order.model.dopo.OrderCountPo;
import com.hhkj.admin.order.model.dopo.OrderPo;
import com.hhkj.admin.order.service.base.OrderService;
import com.hhkj.admin.order.service.biz.OrderBizService;
import com.hhkj.admin.order.service.extend.OrderExtendService;
import com.hhkj.api.order.common.component.supplier.ApiOrderSupplier;
import com.hhkj.api.order.model.req.*;
import com.hhkj.api.order.model.res.ApiOrderCountRes;
import com.hhkj.api.order.model.res.ApiOrderDetailRes;
import com.hhkj.api.order.model.res.ApiOrderIncludeItemRes;
import com.hhkj.api.order.model.res.ApiOrderRes;
import com.hhkj.api.order.service.biz.ApiOrderBizService;
import com.hhkj.api.sale.common.session.holder.ApiSaleSessionHolder;
import com.hhkj.api.sale.common.session.model.LoginSale;
import com.hhkj.payment.wechat.api.WechatMPPayApi;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.paging.PageInfoUtils;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ApiOrderBizServiceImpl
 *
 * @author HHKJ-SERVER-ZJ
 * @since 2023/11/1 16:55
 */
@Service
public class ApiOrderBizServiceImpl implements ApiOrderBizService {

    @Autowired
    private OrderBizService orderBizService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderExtendService orderExtendService;
    @Autowired
    private ApiOrderSupplier apiOrderSupplier;

    @Override
    public boolean payByOffline(ApiOrderOfflinePayReq req) {
        // 1、获取订单信息
        Order orderPo = this.getPendingOrder(req.getId());
        orderPo.setPayReceiptUrl(req.getPayReceiptUrl());
        orderPo.setStatusCode(OrderConst.StatusEnum.PAY_AUDITING.getCode());
        orderPo.setPayMethodCode(OrderConst.PayMethodEnum.OFFLINE.getCode());
        return orderService.updateById(orderPo);
    }

    @Override
    public PrepayWithRequestPaymentResponse payByWechat(ApiOrderWechatPayReq req) {
        // 1、获取订单信息
        Order orderPo = this.getPendingOrder(req.getOrderId());
        int price = orderPo.getPrice().multiply(new BigDecimal(100)).intValue();
        if (StrUtil.isBlank(orderPo.getWechatPrepayId())) {
            PrepayResponse prepayInfo = WechatMPPayApi.prepay(orderPo.getNum(), orderPo.getNum(), price, req.getOpenId());
            orderPo.setWechatPrepayId(prepayInfo.getPrepayId());
            // 记录预支付id
            orderService.updateById(orderPo);
        }
        return WechatMPPayApi.createPrepayWithRequestPaymentResponse(orderPo.getWechatPrepayId());
    }

    /**
     * 获取待支付得订单信息
     *
     * @param id 订单id
     * @return 订单信息
     */
    private Order getPendingOrder(Long id) {
        // 1、获取订单信息
        Order orderPo = orderExtendService.getByIdNotNull(id);
        if (!OrderConst.StatusEnum.PAYING.getCode().equals(orderPo.getStatusCode())) {
            throw new GlobalException("当前订单不允许发起支付");
        }
        Long saleId = ApiSaleSessionHolder.getSaleId();
        if (!saleId.equals(orderPo.getSaleId())) {
            throw new GlobalException("非自己订单无法支付");
        }
        return orderPo;
    }

    @Override
    public ApiOrderCountRes count() {
        Long saleId = ApiSaleSessionHolder.getSaleId();
        OrderCountPo orderCountPo = orderService.countBySaleId(saleId);
        return BeanUtil.toBean(orderCountPo, ApiOrderCountRes.class);
    }

    @Override
    public boolean cancel(ApiOrderCancelReq req) {
        OrderPo orderPo = orderExtendService.getPoByIdNotNull(req.getId());
        if (OrderConst.StatusEnum.PAID.getCode().equals(orderPo.getStatusCode())
                || OrderConst.StatusEnum.CANCEL.getCode().equals(orderPo.getStatusCode())) {
            throw new GlobalException("当前订单不支持取消");
        }
        Long saleId = ApiSaleSessionHolder.getSaleId();
        if (!saleId.equals(orderPo.getSaleId())) {
            throw new GlobalException("没有权限取消当前订单");
        }
        return orderExtendService.cancel(req.getId());
    }

    @Override
    public PageInfo<ApiOrderIncludeItemRes> pagingIncludeItem(ApiOrderIncludeItemReq req) {
        Long saleId = ApiSaleSessionHolder.getSaleId();
        req.setSaleId(saleId);
        List<OrderPo> orderPoList = orderService.listIncludeItem(req);
        PageInfo<ApiOrderIncludeItemRes> result
                = PageInfoUtils.toPageInfo(orderPoList, ApiOrderIncludeItemRes.class);
//        apiOrderSupplier.supplierListItemList(result.getList());
        return result;
    }

    @Override
    public ApiOrderDetailRes getDetailById(Long id) {
        OrderPo orderPo = orderExtendService.getPoByIdNotNull(id);
        Long saleId = ApiSaleSessionHolder.getSaleId();
        if (!orderPo.getSaleId().equals(saleId)) {
            throw new GlobalException("无权限查看该订单信息");
        }
        return BeanUtil.toBean(orderPo, ApiOrderDetailRes.class);
    }

    @Override
    public PageInfo<ApiOrderRes> paging(ApiOrderReq req) {
        Long saleId = ApiSaleSessionHolder.getSaleId();
        req.setSaleId(saleId);
//        this.beforePaging(req);
        List<OrderPo> orderPoList = orderService.listPoByDo(req);
        return PageInfoUtils.toPageInfo(orderPoList, ApiOrderRes.class);
    }

    private void beforePaging(ApiOrderReq req) {
        if (StrUtil.isNotBlank(req.getStatusCode())
                && OrderConst.StatusEnum.PAID.getCode().equals(req.getStatusCode())) {
            req.setStatusCode(StrUtil.EMPTY);

            List<String> statusCodeList = Arrays.asList(OrderConst.StatusEnum.PAY_AUDITING.getCode(),
                    OrderConst.StatusEnum.PAID.getCode());
            req.setStatusCodeList(statusCodeList);
        }
    }

    @Override
    public Order save(ApiOrderSaveReq req) {
        LoginSale loginSale = ApiSaleSessionHolder.getLoginSale();
        List<OrderItem> itemList = req.getItemList().stream()
                .map(itemReq -> BeanUtil.toBean(itemReq, OrderItem.class))
                .collect(Collectors.toList());
        return orderBizService.validateAndCreateOrderByOrderItemList(
                loginSale.getId(),
                itemList,
                OrderConst.SourceTypeCode.APP,
                loginSale.getDefaultCreateBy()
        );
    }
}
